use axum::http::{HeaderMap, Request, Response, StatusCode};
use axum::middleware::Next;
use axum::body::{Body};
use axum::Extension;
use redis::aio::MultiplexedConnection;
use tracing::{debug, error, info, warn};
use crate::utility::jwt::{AccessClaims, JwtUtil, UserInfo};

pub async fn jwt_middleware(
    headers: HeaderMap,
    conn: MultiplexedConnection,
    req: Request<Body>,
    next: Next,
) -> Result<Response<Body>, StatusCode> {
    if let Some(auth_header) = headers.get("authorization") {
        if let Ok(auth_str) = auth_header.to_str() {
            if auth_str.starts_with("Bearer ") {
                let token = auth_str[7..].to_string();
                warn!("收到请求，包含JWT令牌: {}", token);
                // 校验过期时间，和数据完整性，是否已无效
                match JwtUtil::validate_token::<AccessClaims>(token.as_ref()) {
                    Ok(claims) => {
                        debug!("JWT令牌验证成功: {:?}", claims);
                        // 验证通过，继续处理请求
                        let user = UserInfo {
                            user_id: claims.u,
                            authorities: claims.a,
                        };

                        // 查询redis - 检查用户是否已登出
                        let mut redis_conn = conn.clone();
                        let logout_key = format!("user:logout:{}", user.user_id);

                        // 使用 Redis low-level API 查询 key 是否存在
                        match redis::cmd("EXISTS")
                            .arg(&logout_key)
                            .query_async::<bool>(&mut redis_conn)
                            .await {
                            Ok(true) => {
                                // key 存在，表示用户已登出
                                warn!("用户 {} 已登出, token 无效", user.user_id);
                                // return Err(StatusCode::UNAUTHORIZED);
                            },
                            Ok(false) => {
                                // key 不存在，用户未登出，继续处理
                                debug!("用户 {} 未登出，允许访问", user.user_id);
                                let mut req = req;
                                req.extensions_mut().insert(user);
                                return Ok(next.run(req).await);
                            },
                            Err(e) => {
                                // Redis 查询出错，根据业务需求决定是否继续
                                warn!("查询Redis时出错: {:?}，继续处理请求", e);
                            }
                        }
                    },
                    Err(err) => {
                        warn!("JWT令牌验证失败: {:?}", err);
                    }
                }
            }
        }
    }

    Ok(next.run(req).await)
}